﻿

namespace N_dimenslArr
{
    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Linq;
    using System.Text;
    using MapleRock.P2PEmulator.Core;
    using Tao.FreeGlut;
    using Tao.OpenGl;    
    using Tao.Platform;

    public class City
    {
        private const double RenderShift = 0.01;

        private const int RenderCirclePointsNum = 60;

        private double latitude;
        
        private double longitude;

        private double radius;

        private double[] points;

        public City()
        {
            this.latitude = 0;
            this.longitude = 0;
            this.radius = 0;
        }

        public City(double latitude, double longitude, double radius)
        {
            Debug.Assert(latitude != 0, "latitude != 0");
            Debug.Assert(longitude != 0, "longitude != 0");
            Debug.Assert(radius != 0, "radius != 0");
            this.latitude = latitude;
            this.longitude = longitude;
            this.radius = radius;
        }

        public static City FromXmlCity(XmlCity xmlCity)
        {
            City city = new City();
            city.latitude = xmlCity.Latitude;
            city.longitude = xmlCity.Longitude;
            city.radius = xmlCity.Radius;
            city.points = new double[RenderCirclePointsNum * 3];
            city.CalcCirclePointsCoords(city);
            return city;
        }

        public void Render()
        {           
            // активируем режим рисования линий, на основе 
            // последовательного соединения всех вершин в отрезки 
            Gl.glPushAttrib(Gl.GL_LINE_BIT);
            Gl.glPushAttrib(Gl.GL_COLOR);

            Gl.glColor4f(0, 0, 1.0f, 0.4f);

            Gl.glBegin(Gl.GL_LINE_LOOP);

            for (int i = 0; i < (this.points.Length - 2); ++i)
            {
                Gl.glVertex3d(this.points[i], this.points[i + 1], this.points[i + 2]);
                i += 2;
            }       

            Gl.glEnd();

            Gl.glColor4f(0, 0, 1.0f, 0.3f);

            Gl.glBegin(Gl.GL_LINE_LOOP);

            for (int i = 0; i < (this.points.Length - 2); ++i)
            {
                Gl.glVertex3d(this.points[i], this.points[i + 1] + RenderShift, this.points[i + 2]);
                i += 2;
            }

            Gl.glEnd();

            Gl.glBegin(Gl.GL_LINE_LOOP);

            for (int i = 0; i < (this.points.Length - 2); ++i)
            {
                Gl.glVertex3d(this.points[i] + RenderShift, this.points[i + 1], this.points[i + 2]);
                i += 2;
            }

            Gl.glEnd();

            Gl.glBegin(Gl.GL_LINE_LOOP);

            for (int i = 0; i < (this.points.Length - 2); ++i)
            {
                Gl.glVertex3d(this.points[i], this.points[i + 1] - RenderShift, this.points[i + 2]);
                i += 2;
            }

            Gl.glEnd();

            Gl.glBegin(Gl.GL_LINE_LOOP);

            for (int i = 0; i < (this.points.Length - 2); ++i)
            {
                Gl.glVertex3d(this.points[i] - RenderShift, this.points[i + 1], this.points[i + 2]);
                i += 2;
            }

            Gl.glEnd();
            
            Gl.glPopAttrib();
            Gl.glPopAttrib();
        }

        private void CalcCirclePointsCoords(City city)
        {
            const double Delta = (2 * Math.PI) / RenderCirclePointsNum;
            for (int i = 0; i < city.points.Length; i += 3)
            {
                int n = i / 3;
                double x = (city.radius * Math.Cos(n * Delta)) + city.latitude;
                double y = (city.radius * Math.Sin(n * Delta)) + city.longitude;
                city.points[i + 0] = x;
                city.points[i + 1] = y;
                city.points[i + 2] = 0;
            }
        }
    }
}
